package piechowicz.szymon.balloonwars;

import android.app.Activity;
import com.google.android.maps.GeoPoint;

public class Game implements SpeedController.SpeedControllerListener,
        BearingController.BearingControllerListener
{
    
    private static final int GAME_LOOP_INTERVAL = 100; // millis
    
    @SuppressWarnings("unused")
    private final Activity activity;
    private final GameListener listener;
    private final SpeedController speedController;
    private final BearingController bearingController;
    private boolean active;
    private GeoPoint location = new GeoPoint(48858165, 2294587);
    private double speed = 10; // m/s
    private double bearing = 0; // radians clockwise from north; -pi..pi
    
    public Game(Activity activity, GameListener listener)
    {
        this.activity = activity;
        this.listener = listener;
        
        speedController = new SpeedController(activity, this);
        bearingController = new BearingController(activity, this);
    }
    
    public void resume()
    {
        active = true;
        speedController.resume();
        bearingController.resume();
        new Thread(new Runnable()
                {
                    public void run()
                    {
                        gameLoop();
                    }
                }).start();
    }
    
    public void pause()
    {
        active = false;
        speedController.pause();
        bearingController.pause();
    }
    
    private void gameLoop()
    {
        while (active)
        {
            move();
            try
            {
                Thread.sleep(GAME_LOOP_INTERVAL);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    private void move()
    {
        double distanceMeters = speed * ((double)GAME_LOOP_INTERVAL / 1000);
        location = GeoMath.getGreatCirclePoint(location,
                GeoMath.rad2deg(bearing), distanceMeters / 1000);
        listener.onBalloonLocationChanged(location);
    }
    
    private void setSpeed(int speed)
    {
        // slow deceleration when no longer blowing
        if (speed == 0)
            this.speed /= 1.5;
        else
            this.speed = speed;
    }
    
    private void setBearing(double bearing)
    {
        this.bearing = bearing;
    }

    // SpeedControllerListener
    
    public void onSpeedChanged(int speed)
    {
        setSpeed(speed);
    }
    
    // BearingControllerListener
    
    public void onBearingChanged(double bearing)
    {
        setBearing(bearing);
    }

    // Classes, interfaces
    
    public interface GameListener
    {
        
        public void onBalloonLocationChanged(GeoPoint location);
        
    }
    
}
